﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace Fusion
{
    // A 2d Line structure, complete with intersection
    public struct Line
    {
        public Vector2 from;
        public Vector2 to;

        public Line( Vector2 f, Vector2 t )
        {
            from = f;
            to = t;
        }

        // Test intersection with another line
        // Returns intersection point and slice along this line
        public bool Intersect( Vector2 From, Vector2 To, ref float slice, ref Vector2 point )
        { return Intersects( from, to, From, To, ref slice, ref point ); }
        public bool Intersect( Line other, ref float slice, ref Vector2 point )
        { return Intersects( from, to, other.from, other.to, ref slice, ref point ); }
        public static bool Intersects( Vector2 a, Vector2 b, Vector2 c, Vector2 d, ref float slice, ref Vector2 point )
        {
            // Sign of areas correspond to which side of ab points c and d are
            float a1 = Hax.TriArea( a, b, d ); // Compute winding of abd (+ or -)
            float a2 = Hax.TriArea( a, b, c ); // To intersect, must have sign opposite of a1

            // If c and d are on different sides of ab, areas have different signs
            if( a1 * a2 < 0.0f )
            {
                // Compute signs for a and b with respect to segment cd
                float a3 = Hax.TriArea( c, d, a ); // Compute winding of cda (+ or -)
                // Since area is constant a1-a2 = a3-a4, or a4=a3+a2-a1
                //      float a4 = Signed2DTriArea(c, d, b); // Must have opposite sign of a3
                float a4 = a3 + a2 - a1;
                // Points a and b on different sides of cd if areas have different signs
                if( a3 * a4 < 0.0f )
                {
                    // Segments intersect. Find intersection Vector2 along L(t)=a+t*(b-a).
                    // Given height h1 of a over cd and height h2 of b over cd,
                    // t = h1 / (h1 - h2) = (b*h1/2) / (b*h1/2 - b*h2/2) = a3 / (a3 - a4),
                    // where b (the base of the triangles cda and cdb, i.e., the length of cd) cancels out.
                    slice = a3 / (a3 - a4);
                    point = a + slice * (b - a);
                    return true;
                }
            }

            return false;
        }
    }
}